/*
 * Copyright (c) 2009 LastFM.Desktop Anton Pavlik.
 * All Rights Reserved.
 * 
 * You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, 
 * with or without modifications, and in Source or Object form, provided that You meet the following 
 * conditions:
 * 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
 *
 * 2. You must cause any modified files to carry prominent notices stating that You changed the files; 
 * and
 *
 * 3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, 
 * patent, trademark, and attribution notices from the Source form of the Work, excluding those notices 
 * that do not pertain to any part of the Derivative Works.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * You may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0 
 *
 * Unless required by applicable law or agreed to in writing, Licensor provides the Work 
 * (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
 * CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties 
 * or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. 
 * YOU ARE SOLELY RESPONSIBLE FOR DETERMINING THE APPROPRIATENESS OF USING OR REDISTRIBUTING THE WORK
 * AND ASSUME ANY RISKS ASSOCIATED WITH YOUR EXERCISE OF PERMISSIONS UNDER THIS LICENSE. 
 */
package org.shake.lastfm.ui.playlist;

import java.awt.Component;
import java.awt.Container;

import javax.swing.JProgressBar;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bushe.swing.event.annotation.AnnotationProcessor;
import org.bushe.swing.event.annotation.EventTopicSubscriber;
import org.jdesktop.swingx.JXLabel;
import org.jdesktop.swingx.JXPanel;
import org.shake.lastfm.data.MP3Info;
import org.shake.lastfm.event.CaptureTrackRequestEvent;
import org.shake.lastfm.event.CapturingProgressEvent;
import org.shake.lastfm.event.EventTopic;
import org.shake.lastfm.event.TrackInfoObtainedEvent;
import org.shake.lastfm.model.Track;

import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.layout.FormLayout;

public class ProgressPanel extends JXPanel
{
    private static final long serialVersionUID = 2632312609356071208L;
    
    private Log log = LogFactory.getLog(ProgressPanel.class);
    
    private JXLabel infoLabel;
    private JXLabel trackLabel;
    private JXLabel trackTimeLabel;
    private JXLabel trackElapsedTimeLabel;
    
    private JProgressBar progressBar;
    
    private MP3Info currentTrackInfo;
    private long readBytes;
    
    public ProgressPanel()
    {
        super();

        AnnotationProcessor.process(this);
        buildUI();
    }

    private void buildUI()
    {
        this.infoLabel = new JXLabel("Capturing track:");
        this.trackLabel = new JXLabel();
        
        this.trackTimeLabel = new JXLabel("00:00");
        this.trackElapsedTimeLabel = new JXLabel("00:00");
        
        this.progressBar = new JProgressBar(0, 100);
        
        FormLayout layout = new FormLayout("p, 2dlu, p:grow, 2dlu, p");
        DefaultFormBuilder builder = new DefaultFormBuilder(layout, this);
        
        builder.append(this.infoLabel, 4);
        builder.append(this.trackLabel, 4);
        
        builder.append(this.trackElapsedTimeLabel);
        builder.append(this.progressBar);
        builder.append(this.trackTimeLabel);
        
        setEnabledChildren(this, false);
    }
    
    private void setEnabledChildren(Container parent, boolean enabled)
    {
        Component comp;
        for (int i = 0; i < parent.getComponentCount(); i++)
        {
            comp = parent.getComponent(i);
            if (comp instanceof Container)
            {
                setEnabledChildren((Container) comp, enabled);
            }
            else
            {
                comp.setEnabled(enabled);
            }
        }
    }
    
    @EventTopicSubscriber(topic=EventTopic.TRACK_CAPTURE_REQUEST)
    public void onCaptureTrackRequest(String topic, CaptureTrackRequestEvent event)
    {
        log.info("handling " + EventTopic.TRACK_CAPTURE_REQUEST);
        Track trackToCapture = event.getTrack();
        if (trackToCapture != null)
        {
            setEnabledChildren(this, true);
            this.trackLabel.setText(trackToCapture.toString());
            this.progressBar.setValue(0);
            this.progressBar.setMaximum((int) trackToCapture.getDuration());
            this.readBytes = 0;
            this.currentTrackInfo = null;
            this.trackTimeLabel.setText( trackToCapture.getFormattedDuration() );
        }
    }
    
    @EventTopicSubscriber(topic=EventTopic.TRACK_CAPTURING_PROGRESS)
    public void onCapturingProgress(String topic, CapturingProgressEvent event)
    {
        this.readBytes += event.getProgress();
        if (this.currentTrackInfo != null)
        {
            long elapsedTime = calculateElapsedTime(this.readBytes);
            this.progressBar.setValue( (int) elapsedTime );
            this.trackElapsedTimeLabel.setText( Track.getFormattedDuration(elapsedTime) );
        }
    }

    private long calculateElapsedTime(long bytes)
    {
        return (long) ((bytes * 8 ) / (this.currentTrackInfo.getBitRate()));
    }
 
    @EventTopicSubscriber(topic=EventTopic.TRACK_TRACKINFO_OBTAINED)
    public void onTrackInfoObtained(String topic, TrackInfoObtainedEvent event)
    {
        this.currentTrackInfo = event.getMp3Info();
    }
}